# -*- coding: utf-8 -*-            
# @Time : 2024/8/20 16:28
# @FileName: tool.py
# @Target:
import logging, json, codecs, copy, time
from logging.handlers import RotatingFileHandler
from datetime import datetime


from pymongo import MongoClient

formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

def setRotatingRootLogger(filename, level=logging.INFO):
    handler = RotatingFileHandler(filename, encoding='UTF-8', maxBytes=1000000, backupCount=50)
    handler.setFormatter(formatter)
    logger = logging.getLogger()
    logger.setLevel(level)
    logger.addHandler(handler)

# def get_rotatingfilehandler(logfile):
#     handler = RotatingFileHandler(logfile, maxBytes=1000000, backupCount=5)
#     handler.setFormatter(formatter)
#     return handler

# class Mongo_Logger(object):
#     """
#     {
#         'type' : ['INFO' , 'ERROR'],
#         'name' : ['translation', 'qwen2'],
#         'info' : "" ,
#         'date' : datetime
#     }
#     """
#     def __init__(self,
#                  Mongo_URL,
#                  Mongo_Port
#                  ):
#         client = MongoClient(
#             host=Mongo_URL,
#             port=Mongo_Port
#         )
#         db_client = client.get_database(
#             name='log'
#         )
#         self.logger_qwen2 = db_client[
#             'qwen2'
#         ]
#
#     def insert_log(self, dic):
#         self.logger_qwen2.insert_one(dic)
#



class RetryManager:
    # log format :

    def __init__(self, max_retries, delay):
        self.max_retries = max_retries
        self.delay = delay  # 延迟时间，单位为秒

    def execute(self, func, *args, **kwargs):
        # return func(*args, **kwargs)
        attempts = 0
        while attempts < self.max_retries:
            try:
                # 确保 func 是一个可调用的对象，并且正确地传递参数
                return func(*args, **kwargs)
            except Exception as e:
                logging.info(
                    {
                        'type': 'ERROR',
                        'name': 'qwen2',
                        'info': str(e),
                        'date': str(datetime.now())
                    }
                )
                attempts += 1
                if attempts == self.max_retries:
                    raise
                time.sleep(self.delay)  # 等待一段时间后重试
        return {}












































#
#
# class Tool:
#     def clear_sentence(self, customer_voice):
#         return customer_voice.\
#             replace('\r', ''). \
#             replace('\n', '\n'). \
#             replace('\t', ''). \
#             replace('"', ''). \
#             replace("'", "")
#
#     def str2list(self, ori_str):
#         if "'" in ori_str:
#             string = ori_str.replace("'", '"')
#         else:
#             string = ori_str
#         try:
#             string2list = json.loads(string)
#         except Exception as e:
#             string2list = []
#         return string2list
#
# tool = Tool()
#
#
#
# # TODO : 标签加载
# class LABELS:
#     # 客户反馈不在当前标签列表范围内
#     def __init__(self):
#         with codecs.open(filename='labels/csp-labels.json',
#                          mode='r', encoding='utf-8') as fr:
#             self.csp_labels = json.load(fr)
#         self.csp_labels_keys = list(self.csp_labels.keys())
#         with codecs.open(filename='labels/quality-labels.json',
#                          mode='r', encoding='utf-8') as fr:
#             self.quality_labels = json.load(fr)
#         self.quality_labels_keys = list(self.quality_labels.keys())
#
#         with codecs.open(filename='labels/feel-labels.json',
#                          mode='r', encoding='utf-8') as fr:
#             self.feel_labels = json.load(fr)
#         self.feel_labels_keys = list(self.feel_labels)
#         self.clarify_labels = ['客户反馈和车辆相关',
#                                '客户反馈和车辆不相关',
#                                '客户反馈中无法判断是否和车辆相关']
#         self.purchase_labels = ['客户完全不想购买该车辆',
#                                 '购买该车辆意愿一般，当满足一些条件（如降价，提升配置，提升销售服务，改善外观内饰等）后会购买该车辆',
#                                 '购买该车辆意愿强（如满意该车的外观，售价，内饰，销售服务等）',
#                                 '已经购买该车辆或者已经预付车辆购买定金（用车感受，车辆功能描述，用车行为，用车故障等均可视为该标签）',
#                                 '从客户反馈中无法识别客户购车意愿']
#
#
# # labels_obj = LABELS()
#
#
#
#
#
# class PROMPT:
#     def __init__(self):
#         ...
#
#     def _clarify_prompt(self,
#                         customer_voice,
#                         labels=['客户反馈和车辆相关', '客户反馈和车辆不相关', '客户反馈中无法判断是否和车辆相关']):
#         FORMAT = """任务: 对以下客户反馈进行单标签文本分类，识别客户反馈是否和车辆相关。
# 客户反馈: {customer_voice}
# 可供选择的标签列表: {labels}。
# 要求:
# 1.根据客户反馈选择最相关的标签，来识别客户反馈是否和车辆相关。
# 2.确认为单标签文本分类，不要多选，不要生成不在标签列表的标签。
# 输出格式示例:['标签']
# """
#         return FORMAT.format(customer_voice=customer_voice,
#                              labels=str(labels))
#
#     def _purchase_prompt(self,
#                          customer_voice,
#                          labels=['客户完全不想购买该车辆', '购买该车辆意愿一般，当满足一些条件（如降价，提升配置，提升销售服务，改善外观内饰等）后会购买该车辆',
#                                  '购买该车辆意愿强（如满意该车的外观，售价，内饰，销售服务等）', '已经购买该车辆或者已经预付车辆购买定金（用车感受，车辆功能描述，用车行为，用车故障等均可视为该标签）',
#                                  '从客户反馈中无法识别客户购车意愿']):
#         FORMAT = """任务: 对以下客户反馈进行单标签文本分类，识别客户购买该车辆意愿。
# 客户反馈: {customer_voice}
# 可供选择的标签列表: {labels}。
# 要求:
# 1.根据客户反馈选择最相关的标签，来识别客户反馈表达的购车意愿。
# 2.确认为单标签文本分类，不要多选，不要生成不在标签列表的标签。
# 输出格式示例:['标签']
# """
#         return FORMAT.format(customer_voice=customer_voice,
#                              labels=str(labels))
#
#     def _csp_1_prompt(self,
#                       customer_voice,
#                       labels=['智能驾驶',
#                               '车辆部件',
#                               '车辆人车交互功能',
#                               '车辆服务功能以及服务模式',
#                               '车机和其他设备的互联功能',
#                               '车辆电源，电机，电池等三电系统',
#                               '车辆安全功能',
#                               '客户反馈不在当前标签列表范围内']):
#         FORMAT = """任务: 对以下客户关于车辆功能反馈进行多标签分类，并从可供选择的一级标签列表中选择合适的标签进行标注。
# 客户车辆功能反馈: {customer_voice}
# 可供选择的一级标签列表: {labels}。
# 要求:
# 1.根据客户车辆功能反馈选择最相关的一级标签。
# 2.如果客户车辆功能反馈涉及到多个方面，请选择所有适用的一级标签。
# 3.输出标签列表中元素的顺序可以任意排列。
# 输出格式示例:['标签1', '标签2', '标签3']
# """
#         return FORMAT.format(customer_voice=customer_voice, labels=labels)
#
#     def _csp_2_prompt(self,
#                       customer_voice,
#                       first_label,
#                       labels
#                       ):
#         FORMAT = """任务: 对以下客户关于车辆功能反馈进行多标签分类，并从可供选择的二级标签列表中选择合适的标签进行标注。
# 客户车辆功能反馈: {customer_voice}
# 已知的一级标签为：{first_label}。
# 可供选择的二级标签列表: {labels}。
# 要求:
# 1.根据客户车辆功能反馈选择最相关的一级标签。
# 2.如果客户车辆功能反馈涉及到多个方面，请选择所有适用的一级标签。
# 3.输出标签列表中元素的顺序可以任意排列。
# 输出格式示例:['标签1', '标签2', '标签3']
# """
#         return FORMAT.format(customer_voice=customer_voice,
#                              first_label=first_label,
#                              labels=labels)
#
#     def _csp_3_prompt(self,
#                       customer_voice,
#                       labels):
#         ...
#
#     def _feel_1_prompt(self,
#                        customer_voice,
#                        labels=['配置',
#                                '新车交付服务',
#                                '智能座舱',
#                                '操控性',
#                                '品牌口碑和车型口碑',
#                                '舒适性',
#                                '品牌形象和车型形象',
#                                '电池',
#                                '空间',
#                                '动力',
#                                '售后服务',
#                                '内饰',
#                                '外观',
#                                '使用成本',
#                                '安全性',
#                                '价格',
#                                '智能驾驶',
#                                '二手保值率',
#                                '销售服务',
#                                '充电换电',
#                                '质量',
#                                '客户反馈不在当前标签列表范围内']):
#         FORMAT = """任务: 对以下客户关于车辆使用感受反馈进行多标签分类，并从预定义的使用感受一级标签中选择合适的标签进行标注。
# 客户车辆使用感受反馈: {customer_voice}
# 可供选择的使用感受一级标签列表: {labels}
# 要求:
# 1.根据客户车辆使用感受反馈选择最相关的一级标签。
# 2.如果客户车辆使用感受反馈涉及到多个方面，请选择所有适用的一级标签。
# 3.输出标签列表中元素的顺序可以任意排列。
# 输出格式示例:['标签1', '标签2', '标签3']
# """
#         return FORMAT.format(customer_voice=customer_voice, labels=labels)
#
#     def _feel_2_prompt(self,
#                        customer_voice,
#                        labels):
#         ...
#
#     def _quality_1_prompt(self,
#                           customer_voice,
#                           labels=['客户反馈不在当前标签列表范围内', '前后桥及悬挂系统', '销售欺诈', '发动机/电动机', '人员技术', '配件争议', '承诺不兑现', '其他服务问题',
#                                   '其他', '制动系统', '车身附件及电器', '轮胎', '离合器', '服务态度', '变速器', '转向系统', '服务流程不完善', '服务收费']):
#         FORMAT = """任务: 对以下客户关于车辆质量抱怨问题的反馈进行多标签分类，并从预定义的一级标签中选择合适的标签进行标注。
# 客户反馈: {customer_voice}
# 可供选择的一级标签列表: {labels}
# 要求:
# 1.根据客户负面抱怨反馈选择最相关的一级标签。
# 2.如果负面抱怨反馈涉及到多个方面，请选择所有适用的一级标签。
# 3.输出标签列表中元素的顺序可以任意排列。
# 输出格式示例:['标签1', '标签2', '标签3']
# """
#         return FORMAT.format(
#             customer_voice=customer_voice,
#             labels=labels
#         )
#
#     def _quality_2_prompt(self,
#                           customer_voice,
#                           first_label,
#                           labels):
#         FORMAT = """任务: 对以下客户关于车辆质量抱怨问题的反馈进行多标签分类，并从预定义的二级标签中选择合适的标签进行标注。
# 客户反馈: {customer_voice}
# 已知的一级标签: {first_label}
# 可供选择的二级标签列表: {labels}
# 任务:
# 1.根据客户负面反馈选择最相关的二级标签。
# 2.如果负面反馈涉及到多个方面，请选择所有适用的二级标签。
# 3.输出标签列表中元素的顺序可以任意排列。
# 输出格式示例:['标签1', '标签2', '标签3']
# """
#         return FORMAT.format(
#             customer_voice=customer_voice,
#             first_label=first_label,
#             labels=labels
#         )
#
#     def _ner_prompt(self,
#                     customer_voice,
#                     labels):
#         FORMAT = """任务: 从给定的客户反馈中提取与指定标签相关的文本段落。
# 客户反馈: {customer_voice}
# 需要提取的标签: {labels}
# 要求:
# 1.提取与'{labels}'相关的描述。
# 2.不要添加任何额外的信息或创造新的句子。
# 3.如果有客户反馈中有多处不相邻描述和'{labels}'相关，均提取并使用列表方式输出。
# 4.忽略与标签不相关的其他信息。
# 输出格式示例:['描述1', '描述2']
# """
#         return FORMAT.format(customer_voice=customer_voice, labels=labels)
#
#     def _sentiment_prompt(self,
#                           customer_voice,
#                           content,
#                           labels=['正向情感', '中性情感', '负向情感']
#                           ):
#         FORMAT = """任务: 从给定的客户反馈，识别与指定内容相关的情感倾向['正向情感', '中性情感', '负向情感']。
# 客户反馈: {customer_voice}
# 指定内容: {content}
# 可供选择的情感倾向列表: {labels}
# 要求:
# 1.识别客户描述中与'{content}'相关的情感倾向。
# 2.确认为单标签文本分类，不要多选，不要生成不在标签列表的标签。
# 输出格式示例:['描述1', '描述2']"""
#         return FORMAT.format(customer_voice=customer_voice,
#                              content=content,
#                              labels=labels)
#
#     def _preprocess_customer_voice(self, customer_voice):
#         customer_voice = tool.clear_sentence(
#             customer_voice=customer_voice
#         )
#         return customer_voice
#
#     def init_preprocess_labels(self, customer_voice):
#         customer_voice = self._preprocess_customer_voice(
#             customer_voice=customer_voice
#         )
#         clarify_prompt = self._clarify_prompt(
#             customer_voice=customer_voice
#         )
#         purchase_prompt = self._purchase_prompt(
#             customer_voice=customer_voice
#         )
#         quality_1_prompt = self._quality_1_prompt(
#             customer_voice=customer_voice
#         )
#         csp_1_prompt = self._csp_1_prompt(
#             customer_voice=customer_voice
#         )
#         feel_1_prompt = self._feel_1_prompt(
#             customer_voice=customer_voice
#         )
#         return dict(
#             customer_voice=customer_voice,
#             clarify_prompt=clarify_prompt,
#             purchase_prompt=purchase_prompt,
#             quality_1_prompt=quality_1_prompt,
#             csp_1_prompt=csp_1_prompt,
#             feel_1_prompt=feel_1_prompt
#         )
#
#
#
# # prompt = PROMPT()






